# ui.py

import tkinter as tk
from tkinter import ttk, font
from tkinter import messagebox
from roles import ROLES, get_card_value
import os
import sys

try:
    from PIL import Image, ImageTk
except ImportError:
    messagebox.showerror("缺少库", "请先安装Pillow库: pip install Pillow")
    exit()

def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(os.path.dirname(__file__))
    return os.path.join(base_path, relative_path)

class GameUI:
    def __init__(self, root, game):
        self.root = root
        self.game = game
        
        # 定义全局颜色和字体主题
        self.BG_COLOR = "#212121"         # 主背景色 (炭黑)
        self.FRAME_BG_COLOR = "#2c2c2c"   # 框架背景色 (深灰)
        self.FG_COLOR = "#FFFFFF"         # 主要文字颜色 (白色)
        self.HIGHLIGHT_COLOR = "#8B0000"  # 高亮/强调色 (深红)
        self.GOLD_COLOR = "#FFD700"       # 高亮色2 (金色)

        self.TITLE_FONT = font.Font(family="Microsoft YaHei UI", size=28, weight="bold")
        self.HEADER_FONT = font.Font(family="Microsoft YaHei UI", size=16, weight="bold")
        self.DEFAULT_FONT = font.Font(family="Microsoft YaHei UI", size=12)
        self.SMALL_FONT = font.Font(family="Microsoft YaHei UI", size=10)

        self.role_avatar_references = []
        self.current_card_image = None 
        self.summary_card_images = []
        self.current_player_avatar = None

        self.root.title("狂赌之渊同人游戏：STS")
        self.setup_ui()

    def setup_ui(self):
        self.root.geometry("800x600")
        self.root.minsize(600, 400)
        self.root.configure(bg=self.BG_COLOR)
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(3, weight=1)

        style = ttk.Style()
        style.theme_use("clam")
        style.configure("Treeview",
                        background=self.FRAME_BG_COLOR,
                        foreground=self.FG_COLOR,
                        fieldbackground=self.FRAME_BG_COLOR,
                        rowheight=28,
                        font=self.DEFAULT_FONT)
        style.configure("Treeview.Heading",
                        background=self.BG_COLOR,
                        foreground=self.FG_COLOR,
                        font=self.DEFAULT_FONT,
                        relief="flat")
        style.map('Treeview.Heading',
                  background=[('active', self.HIGHLIGHT_COLOR)])
        style.configure("Vertical.TScrollbar",
                        background=self.BG_COLOR,
                        troughcolor=self.FRAME_BG_COLOR,
                        bordercolor=self.BG_COLOR,
                        arrowcolor=self.FG_COLOR)

        self.main_frame = tk.Frame(self.root, bg=self.BG_COLOR)
        self.main_frame.grid(row=0, column=0, sticky="nsew")
        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.rowconfigure(3, weight=1)

        self.player_info_frame = tk.Frame(self.main_frame, bg=self.BG_COLOR)
        self.player_info_frame.grid(row=0, column=0, sticky="nw", padx=10, pady=10)
        self.turn_avatar_label = tk.Label(self.player_info_frame, bg=self.BG_COLOR)
        self.turn_avatar_label.pack(side=tk.LEFT, anchor='n')
        self.turn_player_name_label = tk.Label(self.player_info_frame, text="", font=self.DEFAULT_FONT, justify="left", fg=self.FG_COLOR, bg=self.BG_COLOR)
        self.turn_player_name_label.pack(side=tk.LEFT, anchor='n', padx=10)
        
        self.setup_frame = tk.Frame(self.main_frame, bg=self.BG_COLOR)
        self.setup_frame.grid(row=0, column=0, rowspan=8, sticky="nsew")
        
        tk.Label(self.setup_frame, text="狂赌之渊同人游戏：STS", font=self.TITLE_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(pady=(50, 10))
        tk.Label(self.setup_frame, text="V1.1", font=self.SMALL_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(pady=5)
        
        credits_frame = tk.Frame(self.setup_frame, bg=self.BG_COLOR)
        credits_frame.pack(pady=20)
        tk.Label(credits_frame, text="Creator：鸽子", font=self.SMALL_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(side=tk.LEFT, padx=20)
        tk.Label(credits_frame, text="Programmed by FTP", font=self.SMALL_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(side=tk.LEFT, padx=20)

        self.label = tk.Label(self.setup_frame, text="请输入玩家人数:", font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR)
        self.label.pack(pady=10)
        self.entry = tk.Entry(self.setup_frame, font=self.DEFAULT_FONT, bg=self.FRAME_BG_COLOR, fg=self.FG_COLOR, insertbackground=self.FG_COLOR, width=10, justify='center')
        self.entry.pack(pady=10)
        self.start_button = tk.Button(self.setup_frame, text="开始游戏", font=self.HEADER_FONT, bg=self.HIGHLIGHT_COLOR, fg=self.FG_COLOR, command=self.start_game, relief="flat", padx=20)
        self.start_button.pack(pady=20)

        self.turn_label = tk.Label(self.main_frame, text="", font=self.HEADER_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR)
        self.turn_label.grid(row=2, column=0, pady=(0, 0), sticky="ew")
        
        self.card_label = tk.Label(self.main_frame, bg=self.BG_COLOR)
        self.card_label.grid(row=3, column=0, pady=10, sticky="nsew")

        self.summary_frame = tk.Frame(self.main_frame, bg=self.BG_COLOR)
        self.summary_frame.grid(row=3, column=0, pady=10, sticky="nsew")

        self.choice_frame = tk.Frame(self.main_frame, bg=self.BG_COLOR)
        self.choice_frame.grid(row=4, column=0, pady=10, sticky="ew")
        self.yes_button = tk.Button(self.choice_frame, text="要", font=self.DEFAULT_FONT, bg=self.FRAME_BG_COLOR, fg=self.FG_COLOR, command=lambda: self.make_choice(True), relief="flat", width=15)
        self.yes_button.pack(side=tk.LEFT, padx=10, expand=True, ipady=5)
        self.no_button = tk.Button(self.choice_frame, text="弃牌", font=self.DEFAULT_FONT, bg=self.FRAME_BG_COLOR, fg=self.FG_COLOR, command=lambda: self.make_choice(False), relief="flat", width=15)
        self.no_button.pack(side=tk.LEFT, padx=10, expand=True, ipady=5)

        self.restart_button = tk.Button(self.main_frame, text="重新开始回合", font=self.DEFAULT_FONT, bg=self.FRAME_BG_COLOR, fg=self.FG_COLOR, command=self.restart_turn, relief="flat")
        self.restart_button.grid(row=5, column=0, pady=10, sticky="ew")

        self.action_button_frame = tk.Frame(self.main_frame, bg=self.BG_COLOR)
        self.action_button_frame.grid(row=6, column=0, pady=10, sticky="ew")
        self.next_player_button = tk.Button(self.action_button_frame, text="下一位玩家", font=self.DEFAULT_FONT, bg=self.HIGHLIGHT_COLOR, fg=self.FG_COLOR, command=self.game.next_player, relief="flat")
        self.confirm_turn_button = tk.Button(self.action_button_frame, text="确认回合", font=self.DEFAULT_FONT, bg=self.FRAME_BG_COLOR, fg=self.FG_COLOR, command=self.confirm_turn, relief="flat")
        
        self.result_label = tk.Label(self.main_frame, text="", font=self.HEADER_FONT, justify="center", fg=self.FG_COLOR, bg=self.BG_COLOR)
        self.result_label.grid(row=7, column=0, pady=20, sticky="ew")
        
        columns = ('rank', 'player', 'role', 'score')
        self.result_tree = ttk.Treeview(self.main_frame, columns=columns, show='headings')
        self.result_tree.heading('rank', text='排名')
        self.result_tree.column('rank', width=80, anchor='center')
        self.result_tree.heading('player', text='玩家')
        self.result_tree.column('player', width=120, anchor='center')
        self.result_tree.heading('role', text='角色')
        self.result_tree.column('role', width=150, anchor='center')
        self.result_tree.heading('score', text='最终得分')
        self.result_tree.column('score', width=100, anchor='center')
        self.result_tree.grid(row=1, column=0, rowspan=7, sticky="nsew", padx=20, pady=10)

        self.set_ui_state('initial')
    
    def set_ui_state(self, state):
        self.setup_frame.grid_remove()
        self.player_info_frame.grid_remove()
        self.turn_label.grid_remove()
        self.card_label.grid_remove()
        self.summary_frame.grid_remove()
        self.choice_frame.grid_remove()
        self.restart_button.grid_remove()
        self.action_button_frame.grid_remove()
        self.result_label.grid_remove()
        self.result_tree.grid_remove()
        self.confirm_turn_button.pack_forget()
        self.next_player_button.pack_forget()

        if state == 'initial':
            self.setup_frame.grid()
        elif state == 'selecting_card':
            self.player_info_frame.grid()
            self.turn_label.grid()
            self.card_label.grid()
            self.choice_frame.grid()
        elif state == 'turn_summary' or state == 'kirari_summary':
            self.player_info_frame.grid()
            self.turn_label.grid()
            self.summary_frame.grid()
            self.action_button_frame.grid()
            self.result_label.grid()
            if state == 'kirari_summary':
                self.restart_button.grid()
                self.confirm_turn_button.pack(fill="x", expand=True, ipady=5)
            else:
                self.next_player_button.pack(fill="x", expand=True, ipady=5)
        elif state == 'final_results':
            self.result_tree.grid()

    def start_game(self):
        try:
            num_players = int(self.entry.get())
            if num_players < 1:
                raise ValueError
        except ValueError:
            messagebox.showerror("错误", "请输入有效的玩家人数！")
            return
        # --- 核心修正：删除下面这行错误代码 ---
        # self.set_ui_state('initial') 
        self.game.start_game(num_players)

    def make_choice(self, choice):
        self.game.make_choice(choice)

    def restart_turn(self):
        self.game.restart_turn()

    def show_skill_activation(self, character_name, message):
        messagebox.showinfo(f"{character_name} 技能发动", message)

    def show_all_cards(self, player, cards):
        card_text = "\n".join([f"{card['rank']}{card['suit']}" for card in cards])
        self.show_info("下月売奥理的技能", f"{player} 可以看到所有6张牌:\n{card_text}")

    def show_next_card(self, players, current_player_index, current_card_index):
        self.set_ui_state('selecting_card')
        player = list(players.keys())[current_player_index]
        player_data = players[player]
        
        avatar_path = resource_path(os.path.join("images", ROLES[player_data['role']].get("image_file", "")))
        if os.path.exists(avatar_path):
            img = Image.open(avatar_path)
            img.thumbnail((60, 60))
            self.current_player_avatar = ImageTk.PhotoImage(img)
            self.turn_avatar_label.config(image=self.current_player_avatar)
        else:
            self.turn_avatar_label.config(image="")
        self.turn_player_name_label.config(text=f"{player_data['name']}\n{player_data['role']}", anchor='w')
        
        total_cards_in_hand = len(player_data['cards'])
        if player_data['role'] == "桃喰绮罗莉" and not player_data['used_restart']:
            self.restart_button.grid()
        if player_data['choices_left'] <= 0 or current_card_index >= total_cards_in_hand:
            while current_card_index < total_cards_in_hand:
                card = player_data['cards'][current_card_index]
                player_data['discarded_cards'].append(card)
                current_card_index += 1
            self.show_player_score(player_data)
            return
        card = player_data['cards'][current_card_index]
        self.turn_label.config(text=f"请选择 (剩余选择次数: {player_data['choices_left']})")
        image_path = resource_path(os.path.join("Cards", card['image_file']))
        if os.path.exists(image_path):
            try:
                img = Image.open(image_path)
                img.thumbnail((200, 200 * 3.5 / 2.5))
                self.current_card_image = ImageTk.PhotoImage(img)
                self.card_label.config(image=self.current_card_image, text="")
            except Exception as e:
                self.card_label.config(image="", text=f"图片加载失败")
        else:
            self.card_label.config(image="", text=f"图片丢失")

    def confirm_turn(self):
        self.set_ui_state('turn_summary')

    def show_player_score(self, player_data):
        if player_data['role'] == "桃喰绮罗莉" and not player_data['used_restart']:
            self.set_ui_state('kirari_summary')
        else:
            self.set_ui_state('turn_summary')
        for widget in self.summary_frame.winfo_children():
            widget.destroy()
        self.summary_card_images.clear()
        self.turn_label.config(text=f"{player_data['name']} 的回合结束")
        def create_card_row(parent_frame, title, cards):
            tk.Label(parent_frame, text=title, font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack()
            cards_frame = tk.Frame(parent_frame, bg=self.BG_COLOR)
            cards_frame.pack(pady=5)
            if not cards:
                tk.Label(cards_frame, text="无", font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack()
                return
            for card in cards:
                image_path = resource_path(os.path.join("Cards", card['image_file']))
                if os.path.exists(image_path):
                    img = Image.open(image_path)
                    img.thumbnail((70, 98))
                    photo = ImageTk.PhotoImage(img)
                    self.summary_card_images.append(photo)
                    tk.Label(cards_frame, image=photo, bg=self.BG_COLOR).pack(side=tk.LEFT, padx=3)
        skill_info = self.game.apply_turn_end_skills(player_data)
        if skill_info:
            original_selected = player_data['selected_cards'] + [skill_info['swapped_out']]
            original_selected.remove(skill_info['swapped_in'])
            create_card_row(self.summary_frame, "已选择的牌 (原始):", original_selected)
            skill_frame = tk.Frame(self.summary_frame, bg=self.BG_COLOR)
            skill_frame.pack(pady=10)
            tk.Label(skill_frame, text="技能发动！丢弃", font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(side=tk.LEFT)
            img_out = Image.open(resource_path(os.path.join("Cards", skill_info['swapped_out']['image_file'])))
            img_out.thumbnail((70, 98))
            photo_out = ImageTk.PhotoImage(img_out)
            self.summary_card_images.append(photo_out)
            tk.Label(skill_frame, image=photo_out, bg=self.BG_COLOR).pack(side=tk.LEFT)
            tk.Label(skill_frame, text="，换成", font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR).pack(side=tk.LEFT)
            img_in = Image.open(resource_path(os.path.join("Cards", skill_info['swapped_in']['image_file'])))
            img_in.thumbnail((70, 98))
            photo_in = ImageTk.PhotoImage(img_in)
            self.summary_card_images.append(photo_in)
            tk.Label(skill_frame, image=photo_in, bg=self.BG_COLOR).pack(side=tk.LEFT)
        create_card_row(self.summary_frame, "已选择的牌 (最终):", player_data['selected_cards'])
        create_card_row(self.summary_frame, "弃掉的牌:", player_data['discarded_cards'])
        score = sum(get_card_value(card) for card in player_data['selected_cards'])
        if player_data['role'] in ROLES:
            bonus = ROLES[player_data['role']]["skill"](player_data, self.game)
            score += bonus
        player_data['score'] = score
        self.result_label.config(text=f"本回合总得分: {score}")
        if self.game.current_player_index >= self.game.num_players - 1:
            self.next_player_button.config(text="查看最终结果")

    def hide_restart_button(self):
        self.restart_button.grid_remove()

    def show_result(self, sorted_players, penalty_player):
        self.set_ui_state('final_results')
        for item in self.result_tree.get_children():
            self.result_tree.delete(item)
        for i, (player, data) in enumerate(sorted_players):
            rank = f"第 {i + 1} 名"
            player_name = data['name']
            role = data['role']
            score = data.get('score', 0)
            self.result_tree.insert('', 'end', values=(rank, player_name, role, score))
        if penalty_player:
            messagebox.showwarning("惩罚", f"{penalty_player}（下月売奥理）未进入前两名，需要接受惩罚！")
        
    def show_info(self, title, message):
        messagebox.showinfo(title, message)

    def choose_role(self, player):
        role_window = tk.Toplevel(self.root)
        role_window.title(f"{player} 选择角色")
        role_window.geometry("800x600")
        role_window.minsize(600, 400)
        role_window.configure(bg=self.BG_COLOR)
        
        main_label = tk.Label(role_window, text=f"{player}，请选择一个角色:", font=self.HEADER_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR)
        main_label.pack(pady=10)
        
        canvas_frame = tk.Frame(role_window, bg=self.BG_COLOR)
        canvas_frame.pack(fill="both", expand=True, padx=10)
        canvas = tk.Canvas(canvas_frame, bg=self.BG_COLOR, highlightthickness=0)
        canvas.pack(side=tk.LEFT, fill="both", expand=True)
        scrollbar = ttk.Scrollbar(canvas_frame, orient="vertical", command=canvas.yview)
        scrollbar.pack(side=tk.RIGHT, fill="y")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        role_container = tk.Frame(canvas, bg=self.BG_COLOR)
        canvas.create_window((0, 0), window=role_container, anchor="nw")
        
        role_container.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))

        role_frames = {}
        selected_role = tk.StringVar(value=list(ROLES.keys())[0])

        def update_highlight(*args):
            for r, f in role_frames.items():
                is_selected = (r == selected_role.get())
                new_color = self.GOLD_COLOR if is_selected else self.FRAME_BG_COLOR
                text_color = self.BG_COLOR if is_selected else self.FG_COLOR
                f.config(bg=new_color)
                for widget in f.winfo_children():
                    widget.config(bg=new_color)
                    if isinstance(widget, tk.Frame):
                        for sub_widget in widget.winfo_children():
                            sub_widget.config(bg=new_color, fg=text_color)
                    else:
                        widget.config(bg=new_color, fg=text_color)
        
        selected_role.trace_add("write", update_highlight)

        for role, details in ROLES.items():
            frame = tk.Frame(role_container, borderwidth=1, relief="solid", padx=5, pady=5, bg=self.FRAME_BG_COLOR)
            frame.pack(fill="x", pady=2)
            role_frames[role] = frame
            
            left_frame = tk.Frame(frame, bg=self.FRAME_BG_COLOR)
            left_frame.pack(side=tk.LEFT, padx=5, anchor='n')
            right_frame = tk.Frame(frame, bg=self.FRAME_BG_COLOR)
            right_frame.pack(side=tk.LEFT, padx=5, fill="x", expand=True)

            avatar_path = resource_path(os.path.join("images", details.get("image_file", "")))
            if details.get("image_file") and os.path.exists(avatar_path):
                img = Image.open(avatar_path)
                img.thumbnail((80, 80))
                photo_img = ImageTk.PhotoImage(img)
                avatar_label = tk.Label(left_frame, image=photo_img, bg=self.FRAME_BG_COLOR)
                avatar_label.image = photo_img
                avatar_label.pack()
            
            rb = tk.Radiobutton(right_frame, text=role, variable=selected_role, value=role, font=self.HEADER_FONT, anchor='w', justify='left', activebackground=self.GOLD_COLOR, selectcolor=self.BG_COLOR)
            rb.pack(fill="x")
            
            description_label = tk.Label(right_frame, text=details['description'], font=self.SMALL_FONT, wraplength=500, justify="left", anchor='w')
            description_label.pack(fill="x")

        update_highlight()
            
        confirm_button = tk.Button(role_window, text="确认", font=self.DEFAULT_FONT, bg=self.HIGHLIGHT_COLOR, fg=self.FG_COLOR, command=role_window.destroy, relief="flat")
        confirm_button.pack(pady=10, fill="x", padx=10, ipady=5)

        self.root.wait_window(role_window)
        return selected_role.get()
    
    def prompt_for_target(self, active_player, targets, prompt_message):
        target_window = tk.Toplevel(self.root)
        target_window.title(f"{active_player['name']} 技能发动")
        target_window.geometry("400x300")
        target_window.resizable(False, False)
        target_window.transient(self.root)
        target_window.grab_set()
        target_window.configure(bg=self.BG_COLOR)

        tk.Label(target_window, text=prompt_message, font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR, wraplength=380).pack(pady=20)
        
        selected_target = tk.StringVar()
        if targets:
            selected_target.set(targets[0])
            
        for target_name in targets:
            rb = tk.Radiobutton(target_window, text=target_name, variable=selected_target, value=target_name, font=self.DEFAULT_FONT, fg=self.FG_COLOR, bg=self.BG_COLOR, selectcolor=self.FRAME_BG_COLOR, activebackground=self.BG_COLOR, activeforeground=self.FG_COLOR)
            rb.pack(anchor="w", padx=40)
            
        confirm_button = tk.Button(target_window, text="确认", font=self.DEFAULT_FONT, bg=self.HIGHLIGHT_COLOR, fg=self.FG_COLOR, command=target_window.destroy, relief="flat")
        confirm_button.pack(pady=20, fill="x", padx=40, ipady=5)
        
        self.root.wait_window(target_window)
        return selected_target.get()